package httpproxy.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.Hashtable;
import httpproxy.HttpProxyMain;
import httpproxy.client.ProxyClientThread;
import httpproxy.client.ServerThread;
import httpproxy.util.IProxyClientThreadListener;

public class ProxyServer extends Thread implements IProxyClientThreadListener
{	
	private volatile ServerSocket _serverSocket;
	private int _serverPort = 8080;
	private volatile boolean running = true;
	private Hashtable<Socket,ProxyClientThread> _clientThreads;
	
	public ProxyServer(){}
	
	public ProxyServer(int sPort)
	{	
		try{
			_serverPort = sPort;
			_clientThreads = new Hashtable<Socket,ProxyClientThread>();
			_serverSocket = new ServerSocket(_serverPort);
		}
		catch(IOException ex)
		{
			//System.out.println();
			ex.printStackTrace();
		}
		catch(NumberFormatException nfe)
		{
			nfe.printStackTrace();
		}
	}
	
	
	
	public int getServerPort() {
		return _serverPort;
	}



	public synchronized void setServerPort(int _serverPort) {
		this._serverPort = _serverPort;
	}


	public boolean isRunning()
	{
		return running;
	}
	
	
	public void stopServer()
	{
		running = false;
		try {
			_serverSocket.close();
			this.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException ex) {
			// TODOOO Auto-generated catch block
			ex.printStackTrace();
		}
	}
	
	@Override
	public void run()
	{
		System.out.println(String.format("Server started at %s ", (new Date()).toString()));
		while(running)
		{
			synchronized(_clientThreads)
			{
				try{
					Socket sk = _serverSocket.accept();
					ProxyClientThread pct = HttpProxyMain.IsChainProxy()?(new ProxyClientThread(sk, HttpProxyMain.getChainProxyHost(), HttpProxyMain.getChainProxyPort())):(new ProxyClientThread(sk));
					//ServerThread pct = HttpProxyMain.IsChainProxy()?(new ServerThread(sk, HttpProxyMain.getChainProxyHost(), HttpProxyMain.getChainProxyPort())):(new ServerThread(sk));
					pct.addProxyClientListener(this);
					//_clientThreads.put(sk, pct);
					//System.out.println(String.format("[ProxyServer] Client at %s connected.", sk.getInetAddress().getHostAddress()));
					pct.start();
				}catch(IOException ex)
				{
					ex.printStackTrace();
				}
			}
			
			//System.out.println("[ProxyServer] Testing!");
		}
		
		System.out.println("[ProxyServer] Server is going to stop!");
	}

	@Override
	public synchronized void onClientDone(Socket sk) 
	{
		//ProxyClientThread pct = this._clientThreads.get(sk);
		ProxyClientThread pct = _clientThreads.remove(sk);
		pct.removeProxyClientListener(this);
		
		try {
			sk.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public synchronized void onClientError(Socket sk)
	{
		
	}
}
